/*
 *  NxtInput.mm
 *  NxtFace
 *
 *  Created by Dave on 9/9/06.
 *  Copyright 2006 __MyCompanyName__. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#import "NxtInput.h"

#include "SBJ/NXT/Input.h"
#include "SBJ/NXT/Device.h"

@implementation NxtInput

// Initialization

+ (void)initialize
{
    NSArray* keys = [ NSArray arrayWithObjects: @"Port", nil ];
    [ self setKeys:keys triggerChangeNotificationsForDependentKey: @"Port" ];
    [ self setKeys:keys triggerChangeNotificationsForDependentKey: @"Type" ];
    [ self setKeys:keys triggerChangeNotificationsForDependentKey: @"Name" ];
    [ self setKeys:keys triggerChangeNotificationsForDependentKey: @"Calibrated" ];
    [ self setKeys:keys triggerChangeNotificationsForDependentKey: @"RawValue" ];
    [ self setKeys:keys triggerChangeNotificationsForDependentKey: @"NormalizedValue" ];
    [ self setKeys:keys triggerChangeNotificationsForDependentKey: @"ScaledValue" ];
    [ self setKeys:keys triggerChangeNotificationsForDependentKey: @"CalibratedValue" ];
}

-(id) initInputOf: (NxtDevice*)theDevice on: (unsigned char)port
{
	m_device = theDevice;
	m_input = &( [ m_device deviceRef ]->getInput( (SBJ::NXT::InputPort)port ) );
	return [ super init ];
}

- (void) dealloc
{
	[ super dealloc ];
}
		
// KVC Read-Only Attributes

- (unsigned char) Port
{
	return m_input->getPort();
}

- (NSString*) Name
{
	return [ NSString stringWithFormat: @"%c", '1' + m_input->getPort() ];
}

- (BOOL) Calibrated
{
	return m_input->isCalibrated();
}

- (unsigned short) RawValue
{
	return m_input->getRawValue();
}

- (unsigned short) NormalizedValue
{
	return m_input->getNormalizedValue();
}

- (signed short) ScaledValue
{
	return m_input->getScaledValue();
}

- (signed short) CalibratedValue
{
	return m_input->getCalibratedValue();
}

// KVC Read Attributes

- (ESensorType) Type
{
	switch ( m_input->getType() )
	{
		case SBJ::NXT::sensor_none:
			return sensorType_none;
		case SBJ::NXT::sensor_switch:
			return sensorType_switch;
		case SBJ::NXT::sensor_tempuature:
			return sensorType_tempuature;
		case SBJ::NXT::sensor_reflection:
			return sensorType_reflection;
		case SBJ::NXT::sensor_angle:
			return sensorType_angle;
		case SBJ::NXT::sensor_activeLight:
			return sensorType_activeLight;
		case SBJ::NXT::sensor_inactiveLight:
			return sensorType_inactiveLight;
		case SBJ::NXT::sensor_DB:
			return sensorType_DB;
		case SBJ::NXT::sensor_DBA:
			return sensorType_DBA;
		case SBJ::NXT::sensor_custom:
			return sensorType_custom;
		case SBJ::NXT::sensor_lowspeed:
			return sensorType_lowspeed;
		case SBJ::NXT::sensor_lowspeed9v:
			return sensorType_lowspeed9v;
		case SBJ::NXT::sensor_unknown:
			return sensorType_unknown;
	}
	return sensorType_unknown;
}

- (ESensorMode) Mode
{
	switch ( m_input->getMode() )
	{
		case SBJ::NXT::mode_raw:
			return sensorMode_raw;
		case SBJ::NXT::mode_boolean:
			return sensorMode_boolean;
		case SBJ::NXT::mode_transitionCounter:
			return sensorMode_transitionCounter;
		case SBJ::NXT::mode_periodicCounterMode:
			return sensorMode_periodicCounterMode;
		case SBJ::NXT::mode_pctFullScaleMode:
			return sensorMode_pctFullScaleMode;
		case SBJ::NXT::mode_celsius:
			return sensorMode_celsius;
		case SBJ::NXT::mode_farenheit:
			return sensorMode_farenheit;
		case SBJ::NXT::mode_angleStepsMode:
			return sensorMode_angleStepsMode;
	}
	return sensorMode_raw;
}

// KVC Write Attributes

- (void) setType: (ESensorType)value1
{
	SBJ::NXT::SensorType value = SBJ::NXT::sensor_unknown;
	switch ( value1 )
	{
		case sensorType_none:
			value = SBJ::NXT::sensor_none;
			break;
		case sensorType_switch:
			value = SBJ::NXT::sensor_switch;
			break;
		case sensorType_tempuature:
			value = SBJ::NXT::sensor_tempuature;
			break;
		case sensorType_reflection:
			value = SBJ::NXT::sensor_reflection;
			break;
		case sensorType_angle:
			value = SBJ::NXT::sensor_angle;
			break;
		case sensorType_activeLight:
			value = SBJ::NXT::sensor_activeLight;
			break;
		case sensorType_inactiveLight:
			value = SBJ::NXT::sensor_inactiveLight;
			break;
		case sensorType_DB:
			value = SBJ::NXT::sensor_DB;
			break;
		case sensorType_DBA:
			value = SBJ::NXT::sensor_DBA;
			break;
		case sensorType_custom:
			value = SBJ::NXT::sensor_custom;
			break;
		case sensorType_lowspeed:
			value = SBJ::NXT::sensor_lowspeed;
			break;
		case sensorType_lowspeed9v:
			value = SBJ::NXT::sensor_lowspeed9v;
			break;
		case sensorType_unknown:
			value = SBJ::NXT::sensor_unknown;
			break;
	}
	m_input->setType( value );
}

- (void) setMode: (ESensorMode)value1
{
	SBJ::NXT::SensorMode value = SBJ::NXT::mode_raw;
	switch ( value1 )
	{
		case sensorMode_raw:
			value = SBJ::NXT::mode_raw;
			break;
		case sensorMode_boolean:
			value = SBJ::NXT::mode_boolean;
			break;
		case sensorMode_transitionCounter:
			value = SBJ::NXT::mode_transitionCounter;
			break;
		case sensorMode_periodicCounterMode:
			value = SBJ::NXT::mode_periodicCounterMode;
			break;
		case sensorMode_pctFullScaleMode:
			value = SBJ::NXT::mode_pctFullScaleMode;
			break;
		case sensorType_activeLight:
			value = SBJ::NXT::mode_pctFullScaleMode;
			break;
		case sensorMode_celsius:
			value = SBJ::NXT::mode_celsius;
			break;
		case sensorMode_farenheit:
			value = SBJ::NXT::mode_farenheit;
			break;
		case sensorMode_angleStepsMode:
			value = SBJ::NXT::mode_angleStepsMode;
			break;
	}
	m_input->setMode( value );
}

// Commands

- (void) reset
{
	m_input->reset();
}

// Scriptability

- (NSScriptObjectSpecifier *)objectSpecifier
{
	NSScriptObjectSpecifier *containerRef = [ m_device objectSpecifier ];
	return [ [ [ NSIndexSpecifier allocWithZone: [ self zone ] ]
		initWithContainerClassDescription: [ containerRef keyClassDescription ] 
			containerSpecifier:containerRef key: @"Inputs" index: m_input->getPort() ] autorelease ];
}

- (void)scripterSaysReset:(NSScriptCommand*)command
{ 
    NxtInput* directObj = [command evaluatedReceivers]; 
	if (self != directObj) { 
        //[self returnError:errOSACantAssign string:@"Invalid pairing."]; 
        return; 
    } 
    [ self reset ]; 
}

@end
